package cfdt.common.logging;

import cfdt.common.wrapper.RequestWrapper;
import cfdt.tools.json.JsonUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@Aspect
public class WebLogAspect {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${monitorWaringOpenFlag:#{0}}")
    private int monitorWaringOpenFlag;

    @Pointcut("execution(public * cfdt.ldl..controller..*(..))")
    public void logPointCut() {
    }

    @Before("logPointCut()")
    public void beforeLog(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        logger.info("clientIP: {}", request.getRemoteAddr());
        logger.info("requestURL: {}", request.getRequestURL().toString());
        logger.info("httpMethod: {}", request.getMethod());
        logger.info("className: {}",
                joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        List<String> filterList = new ArrayList<String>();
        filterList.add("base64");
        List<Object> list = new ArrayList<>();
        for (Object object : joinPoint.getArgs()) {
            if (object instanceof HttpSession) {
                continue;
            }
            if (object instanceof HttpServletResponse) {
                continue;
            }
            if (object instanceof RequestWrapper) {
                // 包装过后的不打印日志
                continue;
            }
            list.add(object);
        }
        logger.info("request: {}", JsonUtil.toJsonStr(list));
    }

    /**
     * 在上面的定义的切面方法返回后执行该方法，可以捕获返回对象或者对返回对象就行增强
     */
    @AfterReturning(returning = "object", pointcut = "logPointCut()")
    public void afterReturningLog(JoinPoint joinPoint, Object object) {
        if (object instanceof String) {
            logger.info("response: {}", object);
            // 进行异常监控
            monitorMessage(object.toString(), joinPoint);
        } else {
            List<String> filterList = new ArrayList<String>();
            filterList.add("base64");
            String respStr = JsonUtil.toJsonStr(object);
            logger.info("response: {}", respStr);
            // 进行异常监控
            monitorMessage(respStr, joinPoint);
        }
    }

    private void monitorMessage(String str, JoinPoint joinPoint) {
        try {
            if (monitorWaringOpenFlag == 0) {
                return;
            }
        } catch (Exception e) {
            logger.error("监控预警处理异常：{}", e);
        }
        
        
    }    

}
